package com.maodou.core.utils

import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

/**
 * 通用 JSON 工具：基于 Moshi 将对象/列表/Map 与字符串互转。
 * - 默认提供一个带 Kotlin 反射的全局 Moshi（可覆盖传入你自己的 Moshi）。
 * - 使用内联 + reified 泛型，调用简单：JsonUtils.toJson(value)、JsonUtils.fromJson<T>(json)。
 */
object JsonUtils {
    /** 全局默认 Moshi（如项目中已有 Hilt 注入的 Moshi，优先传入使用注入的实例） */
    val default: Moshi by lazy {
        Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
    }

    // ------- Object -------
    inline fun <reified T> toJson(value: T, moshi: Moshi = default): String {
        val adapter = moshi.adapter(T::class.java)
        return adapter.toJson(value)
    }

    inline fun <reified T> fromJson(json: String, moshi: Moshi = default): T? {
        return try {
            val adapter = moshi.adapter(T::class.java)
            adapter.fromJson(json)
        } catch (e: Throwable) {
            null
        }
    }

    // ------- List -------
    inline fun <reified T> toJsonList(list: List<T>, moshi: Moshi = default): String {
        val type = Types.newParameterizedType(List::class.java, T::class.java)
        val adapter = moshi.adapter<List<T>>(type)
        return adapter.toJson(list)
    }

    inline fun <reified T> fromJsonList(json: String, moshi: Moshi = default): List<T>? {
        return try {
            val type = Types.newParameterizedType(List::class.java, T::class.java)
            val adapter = moshi.adapter<List<T>>(type)
            adapter.fromJson(json)
        } catch (e: Throwable) {
            null
        }
    }

    // ------- Map -------
    inline fun <reified K, reified V> toJsonMap(map: Map<K, V>, moshi: Moshi = default): String {
        val type = Types.newParameterizedType(Map::class.java, K::class.java, V::class.java)
        val adapter = moshi.adapter<Map<K, V>>(type)
        return adapter.toJson(map)
    }

    inline fun <reified K, reified V> fromJsonMap(json: String, moshi: Moshi = default): Map<K, V>? {
        return try {
            val type = Types.newParameterizedType(Map::class.java, K::class.java, V::class.java)
            val adapter = moshi.adapter<Map<K, V>>(type)
            adapter.fromJson(json)
        } catch (e: Throwable) {
            null
        }
    }
}